/*
 * master_manager.c
 *
 *  Created on: Jan 12, 2013
 *      Author: Redchen
 */

#include <pthread.h>
#include <lfs.h>
#include <list.h>
#include <map.h>
#include <vector.h>
#include <iterator_utils.h>
#include <strings.h>
#include <emalloc.h>
#include <logging.h>
#include <rpc.h>
#include <timer.h>
#include <stddefine.h>

#include "master_manager.h"

typedef struct
{
    //meta files
    Map* meta_file_map;
    pthread_rwlock_t meta_file_map_rwlock;

    //resources
    Vector* host_vector;
    pthread_rwlock_t host_vector_rwlock;

} MansterManager;

static Logger* mLog = NULL;

static MansterManager* mManager = NULL;

static boolean check_file_exist_and_extract(const char* namespace, MetaFile* mfile);

void master_manager_init()
{
    mLog = GET_LOGGER("/lfs/mastersevrer");
    mManager = emalloc(sizeof(MansterManager));
    mManager->meta_file_map = map_new(MAP_STRING);
    pthread_rwlock_init(&mManager->meta_file_map_rwlock, NULL);
    mManager->host_vector = vector_new();
    pthread_rwlock_init(&mManager->host_vector_rwlock, NULL);
    //rebuild meta
}

static boolean check_file_exist_and_extract(const char* namespace, MetaFile* mfile)
{
    boolean flag = false;
    pthread_rwlock_rdlock(&mManager->meta_file_map_rwlock);
    if (map_get(mManager->meta_file_map, (void*) namespace, (void**) &mfile))
    {
        flag = true;
    }
    pthread_rwlock_unlock(&mManager->meta_file_map_rwlock);
    return flag;
}

Status master_manager_file_create(const char* namespace, int32_t min_replica, int32_t max_replica)
{
    //check file existing
    MetaFile tmp;
    if (check_file_exist_and_extract(namespace, &tmp))
    {
        return LFS_FILE_IS_EXIST;
    }
    //check resource
    if (vector_size(mManager->host_vector) < max_replica)
    {
        return LFS_LACK_OF_RESOURCE;
    }
    MetaFile* mfile = meta_file_init(namespace, min_replica, max_replica);
    pthread_rwlock_wrlock(&mManager->meta_file_map_rwlock);
    map_put(mManager->meta_file_map, mfile->namespace, mfile);
    pthread_rwlock_unlock(&mManager->meta_file_map_rwlock);
    return LFS_SUCC;
}

Status master_manager_file_write(const char* namespace, int64_t size, int64_t** id)
{
    return LFS_NOT_IMPLEMENT;
}

Status master_manager_file_meta(const char* namespace, /*out*/MetaFile* mfile)
{
    return LFS_NOT_IMPLEMENT;
}

Status master_manager_file_meta_update(const char* namespace, MetaFile* mfile)
{
    return LFS_NOT_IMPLEMENT;
}

Status master_manager_file_delete(const char* namespace)
{
    return LFS_NOT_IMPLEMENT;
}
